import { Config, Inject, Provide } from '@midwayjs/core';
import Snowflake from 'ts-snowflake';
import * as moment from 'moment';
import { JwtService } from '@midwayjs/jwt';
import { Context } from '@midwayjs/koa';
import { ICookieOptions } from '../interface';

class Response {
  /**
   * 成功响应
   * @param data 数据
   * @param message 消息
   * @returns
   */
  success<T = any>(
    data: T = null,
    message: string = '',
    code: number = 200
  ): {
    success: true;
    data: T;
    message: string;
    timestamp: number;
    code: number;
  } {
    return {
      success: true,
      data,
      message,
      timestamp: Date.now(),
      code
    };
  }
  /**
   * 失败响应
   * @param message 消息
   * @returns
   */
  fail(
    message: string = '',
    code: number = -1
  ): {
    success: false;
    data: null;
    message: string;
    timestamp: number;
    code: number;
  } {
    return {
      success: false,
      data: null,
      message,
      timestamp: Date.now(),
      code
    };
  }
}

const snowflake = new Snowflake(31n, 31n);

@Provide()
export default class Utils {
  /**
   * JWT服务
   */
  @Inject()
  jwtService: JwtService;

  @Inject()
  private ctx: Context;

  @Config('cookies')
  private cookieConfig: ICookieOptions;

  /**
   * 响应工具
   */
  public response = new Response();

  /**
   * 生成16进制雪花ID
   * @returns
   */
  public createSnowflakeId16() {
    const bigIntId = snowflake.nextId();
    return bigIntId
      .toString(16) // 转16进制（默认小写）
      .padStart(16, '0') // 高位补0，保证16位
      .toLowerCase(); // 可选：转为大写，统一格式
  }

  /**
   * 日期格式化
   * @param date 日期
   * @param format 格式
   * @returns
   */
  dateFormat(
    date: Date | number | string = new Date(),
    format: string = 'YYYY-MM-DD HH:mm:ss'
  ) {
    return moment(date).format(format);
  }

  /**
   * 解码JWT
   * @param token JWT
   * @returns
   */
  decodeJwt(token: string) {
    return this.jwtService.decode(token);
  }

  getToken() {
    const cookieToken = this.ctx.cookies.get(this.cookieConfig.tokenKey);

    let headerToken = this.ctx.headers[this.cookieConfig.tokenKey];
    if (Array.isArray(headerToken)) {
      headerToken = headerToken[0];
    }

    let authToken = this.ctx.headers.authorization;
    if (authToken && authToken.startsWith('Bearer ')) {
      authToken = authToken.slice(7);
    }

    let queryToken = this.ctx.query[this.cookieConfig.tokenKey];
    if (Array.isArray(queryToken)) {
      queryToken = queryToken[0];
    }

    // 统一获取 token，优先级可调整
    return cookieToken || headerToken || authToken || queryToken || '';
  }

  decodeToken<T = any>(token: string): T {
    return this.jwtService.decode(token) as T;
  }
}
